Web scraping

Próbáljunk meg információt kinyerni a Közbeszerzési Értesítőből!

1. Felderítés

  • Milyen adatok vannak az oldalon?
  • Hogyan érem el az oldalakat? (Lásd http request/response később.)
  • Van-e valami egyértelmű mintája az URL-eknek?
  • Szabad-e robotot használnom? robots.txt
  • Van-e valamelyien "védelem" az oldalon? (Session, cookie, jelszó, javascript, captcha.)

2. Letöltés

  • Hogy működik a web?
  • requests, egy Python library
  • Megoldási módok:
    • brute force: Végigsétálunk a letöltendő oldalak listáján, és mindet letöltjük.
    • crawl: Egy pontból kiindulva a nekünk kellő linkeket végigkövetjük.
    • search: Az oldal keresőjére támaszkodva "crawl"-olunk.

3. Adatkinyerés

4. Adatmentés

Működő scraper példák


In [ ]:
import requests
from datetime import datetime
from time import sleep

In [ ]:
response = requests.get('http://ceumicrodata.github.io/regi.kozbeszerzes.hu/static/KEarchiv/index.html')

In [ ]:
print(response.status_code)
print(response.apparent_encoding)
print(response.content.decode('ISO-8859-2'))

In [ ]:
def mock_download(url):
    '''
    Csinaljunk ugy, mintha letoltottunk volna valamit.
    '''
    print('Most eppen toltom le.....')
    return '<html><body>Ez a {url} tartalma.</body></html>'.format(url=url)
print(mock_download('http://index.hu'))
print(mock_download('http://ceumicrodata.github.io/regi.kozbeszerzes.hu/static/KEarchiv/index.html'))

In [ ]:
def egyszer_letolt(url, cache):
    '''
    A cache egy dictionary, ami az URL-hez rendeli az oldal letoltott tartalmat, pl
    {'http://index.hu': '<html>...</html>', 'http://origo.hu': '<html>...</html>'}.
    
    A fuggveny a megadott URL-t csak akkor tolti le, ha a cache-ben meg nem szerepel.
    Ekkor letolti, es beleteszi a cache-be.
    
    A letoltesre hasznald a mock_download() fuggvenyt! Majd erre is irunk fuggvenyt kesobb.
    '''

In [ ]:
cache = {}
egyszer_letolt('http://index.hu', cache)
egyszer_letolt('http://ceumicrodata.github.io/regi.kozbeszerzes.hu/static/KEarchiv/index.html', cache)
egyszer_letolt('http://index.hu', cache)

In [ ]:
def most():
    return datetime.now()

def regi(timestamp, time_to_live=3000):
    return (most()-timestamp).total_seconds()>time_to_live
akkor = most()
# varjunk 20 masodpercet
sleep(20)
print(regi(akkor, time_to_live=120)) #False
print(regi(akkor, time_to_live=10)) #True

In [ ]:
def frissen_letolt(url, cache, time_to_live=10):
    '''
    A cache egy dictionary, ami az URL-hez rendeli az oldal letoltott tartalmat, es a letoltes idejet, pl
    {'http://index.hu': 
        {'content': '<html>...</html>',
        'timestamp': <timestamp object>}.
    
    A fuggveny a megadott URL-t csak akkor tolti le, ha a cache-ben meg nem szerepel,
    vagy szerepel, de 'time_to_live' masodpercnel regebbi. Ez utobbi ellenorzesere hasznald a
    most() es a regi() fuggvenyt, ezeket egyelore nem kell ertenunk.
    
    Ekkor letolti, es beleteszi a cache-be.
    
    A letoltesre hasznald a mock_download() fuggvenyt! Majd erre is irunk fuggvenyt kesobb.
    '''

In [ ]:
cache = {}
frissen_letolt('http://index.hu', cache, time_to_live=10)
frissen_letolt('http://index.hu', cache, time_to_live=10)
assert regi(cache['http://index.hu']['timestamp']) is False
sleep(12)
frissen_letolt('http://index.hu', cache, time_to_live=10)

In [ ]:
def regi_urlek_listaja(cache, time_to_live=10):
    '''
    A cache egy fenti formaju dictionary. A fuggveny listaban visszaadja a
    'time_to_live'-nel regebbi URL-eket. Ha megvan a megoldas, probald meg
    list comprehensionnel is megcsinalni!
    '''

In [ ]:
def real_download(url):
    '''
    A requests modul hasznalataval toltsd le az URL-t, es a fuggveny adja vissza a tartalmat!
    
    Ha a status code nem 200, akkor adjon vissza egy ures stringet!
    '''

In [ ]:


In [ ]:


In [ ]: